Some Views have Properties which can be changed by the User.
And this is the whole point of such Views - to allow user to SPECIFY some value by interacting with the View.
Example of such View would be a TextField.
Text Field has Property text and User can change it by typing inside the TextField.
But at the same time this Property can also be changed through the code.
When we add TextField View we can give a default value for text property.
And at any time during a program execution we can change it through the code.
In other words as the application is running both User and our Code can freely change this text Property.
In SwiftUI we can't directly access View's Properties during run time.
We can't get reference to TextField View in order to read its text Property in order to see which value User entered.
Instead we need to create a separate Variable which will server as a bridge between our code and View's Property.
So that when User changes View's Property SwiftUI automatically copies entered value into this Variable.
Now if our code wants to read the value of that Property it actually needs to read the Value of that Variable.
SwiftUI takes care that value of View's Property is always in synch with the value of this Variable.
Which means that this also works in the opposite direction.
If our code wants to change View's Property it can do that by changing value of that Variable.
And as we change the value of that Variable SwiftUI will immediately copy this value into Views' Property.
This way our change through the code is presented to the user by changing View's Property.
And this is the purpose of dollar sign. By placing dollar sign before the variable we are telling SwiftUI:
"Please synch this Variable with the View's Property.
Every tie this Variable changes please copy this value to the View's Property.
Every tie this View's Property changes please copy this value to the Variable."
Without the dollar sign we would be telling SwiftUI:
"Please use the current value of this Variable to set this View's Property."
If Variable later changes this will not change that View's Property.
If View's Property later changes, through User's interaction, this will not change that Variable.
In other words without dollar sign Variable and View's Property are not in synch.
And how do we tell SwiftUI to which View's Property to bind the Variable?
This is achieved by using this Variable at appropriate position when adding a View.
For instance to add TextView we need to write Text("Type here", text: $synchVariable).
In this call second parameter refers to text Property. So if we use our bridge Variable in that second place and with dollar
sign we are telling SwiftUI that we want to bind our bridge Variable to text Property.
SwiftUI actually forces us to use dollar sign before the variable for every Property that can be changed by the User.
We can't add TextField View by providing simple String as second parameter.
This results in error "Cannot convert value of type 'String' to expected argument type 'Binding<String>'".
Because as SwiftUI as second parameter expects us to give reference to a String Variable.
And at the same time we need to use @State for that variable because without that Variable can't be changed.